package com.xizi.a_mianshi;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author xizizzz
 * @description: TODO
 * @date 2021-7-8上午 11:05
 */
public class VolatileDemo2 {
    public static void main(String args[]) {
        MyData2 myData2 = new MyData2();

        // 创建20个线程，线程里面进行1000次循环
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                // 里面
                for (int j = 0; j < 1000; j++) {
                    myData2.addPlusPlus();
                    myData2.addAtomic();
                }
            }, String.valueOf(i)).start();
        }

        // 需要等待上面20个线程都计算完成后，在用main线程取得最终的结果值
        // 这里判断线程数是否大于2，为什么是2？因为默认是有两个线程的，一个main线程，一个gc线程
        while (Thread.activeCount() > 2) {
            // yield表示不执行
            Thread.yield();
        }

        // 查看最终的值
        // 假设volatile保证原子性，那么输出的值应该为：  20 * 1000 = 20000
        System.out.println(Thread.currentThread().getName() + "\t finally number value: " + myData2.number);
        System.out.println(Thread.currentThread().getName() + "\t finally atomicNumber value: " + myData2.atomicInteger);
    }
}

class MyData2 {
    // volatile 修饰的关键字，是为了增加 主线程和线程之间的可见性，只要有一个线程修改了内存中的值，其它线程也能马上感知
//    volatile int number = 0;
    int number = 0;

    // 注意，此时number 前面是加了volatile修饰
    // 1. synchronized
    public synchronized void addPlusPlus() {
        number++;
    }

    // 2. 创建一个原子Integer包装类，默认为0
    AtomicInteger atomicInteger = new AtomicInteger();

    public void addAtomic() {
        // 相当于 atomicInter ++
        atomicInteger.getAndIncrement();
    }
}
